package semSimilarity.sentence;

import java.util.List;

import semSimilarity.P;
import semSimilarity.SimilarityGenerator;
import semSimilarity.SimilarityMatrix;
import sentStruct.PartOfSpeech;
import sentStruct.Sentence;

public class SentenceSimilarityGenerator implements SimilarityGenerator<Sentence> {
	
	
	
	public double similarity(Sentence s1, Sentence s2){
		if (s1==null || s2==null) 
			return 0;
		
		double similarity ;
		double a, b, c, d;
				a=structuralSimilarity(s1,s2);
				b=crossedSimilarity(s1,s2);
				c=mixedSimilarity(s1,s2);
				d=equalitiesAverage(s1,s2);
				System.out.println(a+" "+b+" "+c+" "+d);
		
		return P.sentSim.structuralCoeff*a+P.sentSim.crossedCoeff*b+P.sentSim.mixedSimiCoeff*c+P.sentSim.equalityCoeff*d;
		
	}

	private double equalitiesAverage(Sentence s1, Sentence s2) {
		List<? extends PartOfSpeech> l1, l2;
		l1 = s1.getNouns();
		l2 = s2.getNouns();
		return new PartOfSpeechEqualitiy().similarity(l1, l2);
	}

	private double mixedSimilarity(Sentence s1, Sentence s2) {
		List<PartOfSpeech> l1, l2;
		l1 = s1.getAllPartsOfSpeech();
		l2 = s2.getAllPartsOfSpeech();
		return new PartOfSpeechSimGenerator().similarity(l1, l2);
	}

	private double crossedSimilarity(Sentence s1, Sentence s2) {
		PartOfSpeechSimGenerator ps = new PartOfSpeechSimGenerator();
		double basecoeff=0;
		double similarity=0;
		
		if (s1.getNouns().size()!=0||s2.getNouns().size()!=0){
			similarity+=P.crossSim.nounsCoef*ps.similarity(s1.getNouns(), s2.getNouns());
			basecoeff+=P.crossSim.nounsCoef;
			
		}
		
		if (s1.getPronouns().size()!=0||s2.getPronouns().size()!=0){
			similarity+=P.crossSim.proNounCoeff*ps.similarity(s1.getPronouns(), s2.getPronouns());
			basecoeff+=P.crossSim.proNounCoeff;
			
		}
		if (s1.getVerbs().size()!=0||s2.getVerbs().size()!=0){
			similarity+=P.crossSim.verbCoeff*ps.similarity(s1.getVerbs(), s2.getVerbs());
			basecoeff+=P.crossSim.verbCoeff;
			
		}
		
		if (s1.getAdjectivesAndAdverbs().size()!=0||s2.getAdjectivesAndAdverbs().size()!=0){
			similarity+=P.crossSim.adjsAndAdvs*ps.similarity(s1.getAdjectivesAndAdverbs(), s2.getAdjectivesAndAdverbs());
			basecoeff+=P.crossSim.adjsAndAdvs;
		}
		return similarity/basecoeff;
		
	/*
	
		return ((P.crossSim.nounsCoef*ps.similarity(s1.getNouns(), s2.getNouns()))+
				(P.crossSim.proNounCoeff*ps.similarity(s1.getPronouns(), s2.getPronouns()))+
				(P.crossSim.verbCoeff*ps.similarity(s1.getVerbs(), s2.getVerbs()))+
				(P.crossSim.adjsAndAdvs*ps.similarity(s1.getAdjectivesAndAdverbs(), s2.getAdjectivesAndAdverbs())));
*/
	}

	private double structuralSimilarity(Sentence s1, Sentence s2) {
		NounSimGenerator nounGen = new NounSimGenerator();
		VerbSimGenerator verbGen = new VerbSimGenerator();
		PartOfSpeechSimGenerator pofGen = new PartOfSpeechSimGenerator();
		double similarity=0;
		double basecoeff=0;
		
		if (s1.getSubjects().size()!=0||s2.getSubjects().size()!=0){
			similarity+=P.structSim.subCoeff*nounGen.similarity(s1.getSubjects(), s2.getSubjects());
			basecoeff+=P.structSim.subCoeff;
			
		}
		
		if (s1.getVerbs().size()!=0||s2.getVerbs().size()!=0){
			similarity+=P.structSim.verbCoeff*verbGen.similarity(s1.getVerbs(), s2.getVerbs());
			basecoeff+=P.structSim.verbCoeff;
		}
		if (s1.getObjects().size()!=0||s2.getObjects().size()!=0){
			similarity+=P.structSim.objCoeff*nounGen.similarity(s1.getObjects(), s2.getObjects());
			basecoeff+=P.structSim.objCoeff;
		}
		if (s1.getPrepositionObjects().size()!=0||s2.getPrepositionObjects().size()!=0){
			similarity+=P.structSim.prepositionObjects*pofGen.similarity(s1.getPrepositionObjects(), s2.getPrepositionObjects());
			basecoeff+=P.structSim.prepositionObjects;
		}
		
		/*
		Double subjectSim, predicateSim, objectSim, prepositionObjectsSim;
		subjectSim = nounGen.similarity(s1.getSubjects(), s2.getSubjects());
		predicateSim = verbGen.similarity(s1.getVerbs(), s2.getVerbs());
		objectSim = nounGen.similarity(s1.getObjects(), s2.getObjects());
		prepositionObjectsSim = pofGen.similarity(s1.getPrepositionObjects(), s2.getPrepositionObjects());
		
		return subjectSim*P.structSim.subCoeff+ predicateSim*P.structSim.verbCoeff+
				objectSim*P.structSim.objCoeff+prepositionObjectsSim*P.structSim.prepositionObjects;
				*/
		return similarity/basecoeff;
	}


	@Override
	public double similarity(List<? extends Sentence> list1, List<? extends Sentence> list2) {
		if (list1==null||list2==null)
			return 0;
		SimilarityMatrix<Sentence> matrix = new SimilarityMatrix<Sentence>(list1, list2, this);
		
		return matrix.maxSimilarityAverage();
	}
	
	

}
